﻿using System;
using System.Collections.Generic;
using System.Configuration;
using Citi.PTSConsolidation.Domain;
using Citi.PTSConsolidation.SchedulerUI.Bases;
using Citi.PTSConsolidation.SchedulerUI.SchedulerWcf;
using Citi.RoutineBase;
using SqlHelper = Citi.PTSConsolidation.Domain.Utils.SqlHelper;

namespace Citi.PTSConsolidation.SchedulerUI
{
    internal class ClientAllocationExtraction
    {
        private static string PtsConnectionString { get { return ConfigurationManager.AppSettings["PtsConnectionString"]; } }
        private static string DWReportingConnectionString { get { return ConfigurationManager.AppSettings["DWReportingConnectionString"]; } }
        private static string ExcelClientAllocation { get { return ConfigurationManager.AppSettings["ExcelClientAllocation"]; } }

        public static void ExtractData(ICurrentAction currentAction, IDictionary<string, object> parameters, DateTime referenceDate, int year, string robotUsername, string robotPassword)
        {
            currentAction.Description = string.Format("Client Allocation: Copy has started at {0}", DateTime.Now);           

            var query = ClientAllocation.GetEntrepotQueryString(year);
            currentAction.Description = query;
            currentAction.StartLog("Copying data from entrepot to PTS database");
            
            SqlHelper.CopyDataFromAnotherDatabase(DWReportingConnectionString, query, "ClientAllocation", PtsConnectionString, ClientAllocation.ColumnMappings);
            currentAction.StopLog();

            UpdateBookOfWork(year, referenceDate, ref currentAction);

            DeleteImportedData(currentAction);

            currentAction.Description = string.Format("Client Allocation: Copy has finished at {0}", DateTime.Now);

            GetSaveClientVarianceQuery(currentAction, year, referenceDate);
        }

        private static void GetSaveClientVarianceQuery(ICurrentAction currentAction, int year, DateTime referenceDate)
        {
            currentAction.Description = "Saving Client Variance";
            var query = BookOfWork.GetSaveClientVarianceQuery(year, referenceDate);
            currentAction.Description = query;
            SqlHelper.ExecuteReader(query, PtsConnectionString);
        }

        private static void DeleteImportedData(ICurrentAction currentAction)
        {
            currentAction.Description = "Deleting Data";
            var query = ClientAllocation.GetQueryDelete();
            currentAction.Description = query;
            SqlHelper.ExecuteReader(query, PtsConnectionString);
        }

        public static void UpdateBookOfWork(int year, DateTime referenceDate, ref ICurrentAction currentAction)
        {
            currentAction.Description = "Updating 'Client Allocation'";
            var query = ClientAllocation.GetQueryUpdateAllocation(year, referenceDate);
            currentAction.Description = query;
            SqlHelper.ExecuteReader(query, PtsConnectionString);
        }

        public static void ScheduleLaggedReport(ref ICurrentAction currentAction, Dictionary<string, object> parameters)
        {
            var laggedRoutineId = int.Parse(parameters["LaggedReportRoutineId"].ToString());

            currentAction.Description = "Scheduler Lagged Report";

            using (var client = new ScheduleClient())
                client.ExecuteRoutineOnDemandById(laggedRoutineId, null);
        }
    }

    public class ClientAllocationExtractionCurrentYear : CurrentYear
    {
        protected override void ExecuteProcess(DateTime referenceDate, ref ICurrentAction currentAction, string networkUser, string networkPassword, Dictionary<string, object> parameters)
        {
            ClientAllocationExtraction.ExtractData(currentAction, parameters, referenceDate, referenceDate.Year, networkUser, networkPassword);
        }
    }

    public class ClientAllocationExtractionNextYear : NextYear
    {
        public new IEnumerable<RoutineParameter> Parameters
        {
            get
            {
                return new List<RoutineParameter> { 
                    new RoutineParameter{ Description = "Start Month to generate Next Year Report", Name ="StartMonth", Nullable= true, Required = false, Type = typeof(int)},
                    new RoutineParameter{ Description = "Lagged Report routine id", Name ="LaggedReportRoutineId", Nullable= false, Required = true, Type = typeof(int)}
                };
            }
        }

        protected override void ExecuteProcess(DateTime referenceDate, ref ICurrentAction currentAction, string networkUser, string networkPassword, Dictionary<string, object> parameters)
        {
            ClientAllocationExtraction.ExtractData(currentAction, parameters, referenceDate, referenceDate.Year + 1, networkUser, networkPassword);
            ClientAllocationExtraction.ScheduleLaggedReport(ref currentAction, parameters);
        }
    }

    public class ClientAllocationExtractionPreviousYear : PreviousYear
    {
        public new IEnumerable<RoutineParameter> Parameters
        {
            get
            {
                return new List<RoutineParameter> { 
                    new RoutineParameter{ Description = "Finish Month to generate Previous Year Report", Name ="FinishMonth", Nullable= true, Required = false, Type = typeof(int)},
                    new RoutineParameter{ Description = "Lagged Report routine id", Name ="LaggedReportRoutineId", Nullable= false, Required = true, Type = typeof(int)}
                };
            }
        }

        protected override void ExecuteProcess(DateTime referenceDate, ref ICurrentAction currentAction, string networkUser, string networkPassword, Dictionary<string, object> parameters)
        {
            ClientAllocationExtraction.ExtractData(currentAction, parameters, referenceDate, referenceDate.Year - 1, networkUser, networkPassword);
            ClientAllocationExtraction.ScheduleLaggedReport(ref currentAction, parameters);
        }
    }
}